#include "Common/Unit/BaseUnit/Utftranscode.h"
#include "Common/Unit/Transcodestring.h"


using namespace Common;

CLangException::CLangException( const char* exp )
:CException( exp , ExceptionCodeLang )
{
}

CLangException::~CLangException()
{
}

std::string Common::utf162utf8( const std::wstring& wstr )
{
	int len = (int)wstr.length() * 3 / 2 + 3;
	char* buf = (char*)malloc( len );
	if( cdf::CTranscoder::utf16s2utf8s( wstr.c_str() , buf , len ) < 0 )
	{
		COMMON_THROW_EXCEPTION( CLangException , "cf::CTranscoder::utf16s2utf8s" );
	}
	std::string str = buf;
	return str;
}

std::wstring Common::utf82utf16( const std::string& str )
{
	int len = (int)str.length() + 1;
	wchar_t* buf = (wchar_t*)malloc( len * sizeof( wchar_t ) );
	if( cdf::CTranscoder::utf8s2utf16s( str.c_str() , buf , len ) < 0 )
	{
		COMMON_THROW_EXCEPTION( CLangException , "cdf::CTranscoder::utf8s2utf16s" );
	}
	std::wstring wstr = buf;
	return wstr;
}
bool Common::isutf8( const char* buf , int size )
{
	bool isUtf8 = true;
	const unsigned char* start = (const unsigned char*)buf;
	const unsigned char* end = (const unsigned char*)buf + size;
	while (start < end)
	{
		if (*start < 0x80)
		{
			start++;
		}
		else if (*start < (0xC0))
		{
			isUtf8 = false;
			break;
		}
		else if (*start < (0xE0))
		{
			if (start >= end - 1)
			{
				break;
			}
			if ((start[1] & (0xC0)) != 0x80)
			{
				isUtf8 = false;
				break;
			}
			start += 2;
		} 
		else if (*start < (0xF0))
		{
			if (start >= end - 2)
			{
				break;
			}
			if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80)
			{
				isUtf8 = false;
				break;
			}
			start += 3;
		} 
		else
		{
			isUtf8 = false;
			break;
		}
	}
	return isUtf8;
}